package com.jcfk.system.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jcfk.common.cache.redis.service.RedisStringService;
import com.jcfk.common.core.context.SpringContextUtils;
import com.jcfk.common.security.utils.SecurityUtils;
import com.jcfk.system.domain.dto.SysOrganizationDTO;
import com.jcfk.system.domain.model.SendMsgModel;
import com.jcfk.system.domain.po.*;
import com.jcfk.system.utils.WechatConfigUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.impl.WxCpMessageServiceImpl;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 发送企业微信推送
 */
@Component("sendWeChatService")
public class SendWeChatService {

    @Autowired
    private RedisStringService redisStringService;

    @Autowired
    private SysUserAccountService sysUserAccountService;

    @Value("${wx-cp-config.agentid}")
    private Integer agentId;
    @Value("${wx-cp-config.secret}")
    private String secret;
    // 企业id
    @Value("${wx-cp-config.corpid}")
    private String corpId;
    // 企业id
    @Value("${wx-cp-config.tokenUrl}")
    private String tokenUrl;
    // 企业id
    @Value("${wx-cp-config.userIdUrl}")
    private String userIdUrl;

    private static SysMessageSendUserService sysMessageSendUserService;


    private static SysMessageSendRecordService sysMessageSendRecordService;


    private static SysMessageSendRecordDetailsService sysMessageSendRecordDetailsService;

    private static SysBusinessGroupUserService sysBusinessGroupUserService;
    /**
     * 多级分类服务
     */
    private static RefUserOrganizationMappingService refUserOrganizationMappingService;
    private static SysOrganizationService sysOrganizationService;

    private static SysInternalMessageService sysInternalMessageService;

    private static WebSocketMessageService webSocketMessageService;
    private static SysUserService sysUserService;

    // 使用静态代码块及SpringContextUtils获取对象
    static {
        sysMessageSendUserService = SpringContextUtils.getBean(SysMessageSendUserService.class);
        sysMessageSendRecordService = SpringContextUtils.getBean(SysMessageSendRecordService.class);
        sysMessageSendRecordDetailsService = SpringContextUtils.getBean(SysMessageSendRecordDetailsService.class);
        sysBusinessGroupUserService = SpringContextUtils.getBean(SysBusinessGroupUserService.class);
        refUserOrganizationMappingService = SpringContextUtils.getBean(RefUserOrganizationMappingService.class);
        sysInternalMessageService = SpringContextUtils.getBean(SysInternalMessageService.class);
        webSocketMessageService = SpringContextUtils.getBean(WebSocketMessageService.class);
        sysOrganizationService = SpringContextUtils.getBean(SysOrganizationService.class);
        sysUserService = SpringContextUtils.getBean(SysUserService.class);
    }

    public void sendWeChat(SendMsgModel message, SysMessageSendRecord record) {

        // 接收人
        String[] fruits = {"3", "4"};
        QueryWrapper<SysMessageSendUser> sysMessageSendUserQueryWrapper = new QueryWrapper<>();
        sysMessageSendUserQueryWrapper.lambda().eq(SysMessageSendUser::getTempleId, record.getTempleId()).eq(SysMessageSendUser::getDeleted, 0).notIn(SysMessageSendUser::getType, fruits);
        List<SysMessageSendUser> list = sysMessageSendUserService.list(sysMessageSendUserQueryWrapper);

        // 用户id
        List<String> userIds = new ArrayList<>();
        List<String> groupId = new ArrayList<>();

        for (SysMessageSendUser user : list) {
            if (!StringUtils.isEmpty(user.getOrganizationId()) && StringUtils.isEmpty(message.getOrganizationId())) {
                message.setOrganizationId(user.getOrganizationId());
            }
            if (!StringUtils.isEmpty(user.getRecevieUserId())) userIds.add(user.getRecevieUserId());
            if (!StringUtils.isEmpty(user.getGroupId())) groupId.add(user.getGroupId());
        }


        // 根据组织 赋值接收人id
        if (!StringUtils.isEmpty(message.getOrganizationId())) {
            SysOrganizationDTO sysOrganization = sysOrganizationService.get(message.getOrganizationId());
            QueryWrapper<SysOrganization> sysOrganizationQueryWrapper = new QueryWrapper<>();
            sysOrganizationQueryWrapper.lambda().likeRight(SysOrganization::getAllId, sysOrganization.getAllId()).eq(SysOrganization::getDeleted, 0);
            List<SysOrganization> organizations = sysOrganizationService.list(sysOrganizationQueryWrapper);
            List<String> oragIds = organizations.stream().map(SysOrganization::getId).collect(Collectors.toList());

            QueryWrapper<RefUserOrganizationMapping> refUserOrganizationMappingQueryWrapper = new QueryWrapper<>();
            refUserOrganizationMappingQueryWrapper.lambda().in(RefUserOrganizationMapping::getOrganizationId, oragIds);
            List<String> ids = refUserOrganizationMappingService.list(refUserOrganizationMappingQueryWrapper).stream().map(RefUserOrganizationMapping::getUserId).collect(Collectors.toList());
            message.getReceiveUserIds().addAll(ids);
        }

        // 根据组别 赋值接收人id
        if (message.getBusinessGroupId() == null || message.getBusinessGroupId().size() > 0) {
            message.setBusinessGroupId(groupId);
            if (message.getBusinessGroupId() == null || message.getBusinessGroupId().size() > 0) {
                QueryWrapper<SysBusinessGroupUser> sysBusinessGroupUserQueryWrapper = new QueryWrapper<>();
                sysBusinessGroupUserQueryWrapper.lambda().in(SysBusinessGroupUser::getBusinessId, message.getBusinessGroupId()).eq(SysBusinessGroupUser::getDeleted, 0);
                List<String> ids = sysBusinessGroupUserService.list(sysBusinessGroupUserQueryWrapper).stream().map(SysBusinessGroupUser::getUserId).collect(Collectors.toList());
                message.getReceiveUserIds().addAll(ids);
            }
        }

        // 接收人id赋值
        if (message.getReceiveUserIds() == null && message.getReceiveUserIds().size() <= 0) {
            message.getReceiveUserIds().addAll(userIds);
        }

        // 接收人去重
        message.setReceiveUserIds(message.getReceiveUserIds().stream().distinct().collect(Collectors.toList()));
        QueryWrapper<SysUserAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(SysUserAccount::getUserId, message.getReceiveUserIds());
        List<SysUserAccount> accounts = sysUserAccountService.list(queryWrapper);
        List<String> accountIds = accounts.stream().filter(item -> item.getWecomId() != null || !"".equals(item.getWecomId())).map(SysUserAccount::getWecomId).collect(Collectors.toList());
        List<String> accountUserIds = new ArrayList<>();
        for (SysUserAccount account : accounts) {
            if (account.getWecomId() != null && !"".equals(account.getWecomId())){
                accountUserIds.add(account.getUserId());
            }
        }

        message.getReceiveUserIds().removeAll(accountUserIds);

        List<String> wxChatid = getUserId(getWXAccessToken(), message.getReceiveUserIds(), accountUserIds);

        accountIds.addAll(wxChatid);
        // 根据手机号获取企业微信的用户id
        String sendUerid = String.join("|", accountIds);

        // 微信消息对象
        WxCpMessageServiceImpl wxCpMessageService = new WxCpMessageServiceImpl(WechatConfigUtil.getWxCpService());
        WxCpMessage wxCpMessage = new WxCpMessage();
        wxCpMessage.setSafe("111");
        wxCpMessage.setMsgType("textcard");  // 设置消息形式，这里设置为卡片消息

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String time = sdf.format(new Date());

        // 设置发送用户
        wxCpMessage.setToUser(sendUerid);
        List<SysMessageSendRecordDetails> records = new ArrayList<>();
        // 发送记录入库
        for (String receiveUserId : accountUserIds) {
            SysMessageSendRecordDetails details = new SysMessageSendRecordDetails();
            details.setRecevieUserId(receiveUserId);
            details.setTitle(record.getTitle());
            details.setContent(message.getMsgBody());
            details.setMessageId(record.getId());
            details.setCreatedUserId(record.getCreatedUserId());
            details.setCreateTime(new Date());
            details.setCreatedUserId(record.getCreatedUserId());
            details.setCreatedUserName(record.getCreatedUserName());
            records.add(details);
        }

        message.getReceiveUserIds().removeAll(accountUserIds);
        // 发送记录入库
        for (String receiveUserId : message.getReceiveUserIds()) {
            SysMessageSendRecordDetails details = new SysMessageSendRecordDetails();
            details.setRecevieUserId(receiveUserId);
            details.setTitle(record.getTitle());
            details.setMessageStatus("2");
            details.setContent(message.getMsgBody());
            details.setMessageId(record.getId());
            details.setCreatedUserId(record.getCreatedUserId());
            details.setCreateTime(new Date());
            details.setCreatedUserId(record.getCreatedUserId());
            details.setCreatedUserName(record.getCreatedUserName());
            records.add(details);
        }

        if (records.size() > 0) sysMessageSendRecordDetailsService.saveBigBatch(records);

        // 发送的标题
        wxCpMessage.setTitle(message.getTitle());


        // 发送内容
        wxCpMessage.setDescription(message.getMsgBody());

        // 设置跳转url
        wxCpMessage.setUrl(message.getUrl());
        wxCpMessage.setBtnTxt("详情");
        try {
            wxCpMessageService.send(wxCpMessage);  // 发送消息
        } catch (WxErrorException e) {
        }

        if (message.getReceiveUserIds().size() > 0) {
            record.setMessageStatus(3);
        } else {
            record.setMessageStatus(1);
        }
        // 更新状态

        sysMessageSendRecordService.updateById(record);
    }


    /**
     * @param accessToken 企业微信的token
     * @param mobile      用户电话号码
     * @return String
     */
    public String getUserId(String accessToken, String mobile) {
        ;
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("mobile", mobile);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, (MultiValueMap<String, String>) headers);

        Map<String, Object> response = restTemplate.postForObject(userIdUrl + "?access_token=" + accessToken, requestEntity, Map.class);

        if (response != null && response.containsKey("userid")) {
            return (String) response.get("userid");
        } else {
            return "";
        }
    }

    /**
     * @param accessToken 企业微信的token
     * @param UserIds     用户电话号码
     * @return String
     */
    public List<String> getUserId(String accessToken, List<String> UserIds, List<String> userid) {
        List<String> wxChatid = new ArrayList<>();
        List<SysUser> users = new ArrayList<>();
        if (UserIds.size() > 0) users = sysUserService.listByIds(UserIds);
        for (SysUser user : users) {
            if (user.getMobile() != null && !"".equals(user.getMobile())) {
                RestTemplate restTemplate = new RestTemplate();

                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);

                Map<String, Object> requestBody = new HashMap<>();
                requestBody.put("mobile", user.getMobile());

                HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, (MultiValueMap<String, String>) headers);

                Map<String, Object> response = restTemplate.postForObject(userIdUrl + "?access_token=" + accessToken, requestEntity, Map.class);
                if (response != null && response.containsKey("userid")) {
                    userid.add(user.getId());
                    wxChatid.add(response.get("userid").toString());
                    String qiyeid = response.get("userid").toString();
                    QueryWrapper<SysUserAccount> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda().eq(SysUserAccount::getUserId, user.getId());
                    SysUserAccount sysUserAccount = sysUserAccountService.getOne(queryWrapper);
                    if (sysUserAccount == null) sysUserAccount = new SysUserAccount();
                    sysUserAccount.setUserId(user.getId());
                    sysUserAccount.setWecomId(qiyeid);
                    sysUserAccount.setCreatedUserId("1");
                    sysUserAccount.setCreatedUserName("管理员");
                    sysUserAccount.setCreateTime(new Date());
                    sysUserAccount.setLastUpdatedUserId("1");
                    sysUserAccount.setLastUpdateTime(new Date());
                    sysUserAccount.setLastUpdatedUserName("管理员");
                    sysUserAccount.setDeleted(0);
                    if (sysUserAccount.getId() != null && !"".equals(sysUserAccount.getId()))
                        sysUserAccountService.updateById(sysUserAccount);
                    else sysUserAccountService.save(sysUserAccount);
                }
            }
        }
        return wxChatid;
    }


    /**
     * 获取企业微信的accessToken
     */
    public String getWXAccessToken() {
        // 从Redis中获取access_token
        String accessResult = redisStringService.getValue("wx_access_token" + corpId);
        if (accessResult != null) {
            return accessResult;
        }
        // 构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("corpid", corpId);
        paramMap.put("corpsecret", secret);

        // 发送GET请求获取access_token
        String response = HttpUtil.get(tokenUrl, paramMap);
        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(response);

        // 检查请求结果是否成功
        if (jsonObject.getInt("errcode") != 0) {
            throw new RuntimeException("获取企业微信access_token失败：" + jsonObject.getStr("errmsg"));
        }

        // 缓存wx_access_token到redis
        redisStringService.setValue("wx_access_token" + corpId, jsonObject.getStr("access_token"), jsonObject.getLong("expires_in"), TimeUnit.SECONDS);

        return jsonObject.getStr("access_token");
    }


}
